using B.S.Medical.Api.Read.Application.Command.Payment;
using B.S.Medical.Domain.Medical;
using B.S.Medical.Domain.Payment;
using B.S.Medical.ErrorCode;
using B.S.Medical.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.Medical.Api.Read.Application.Handler.Payment
{
    /// <summary>
    /// 获取退款信息处理器
    /// </summary>
    public class GetRefundInfoHandler : IRequestHandler<GetRefundInfoCommand, ApiResult<RefundInfoDto>>
    {
        private readonly IBaseRepository<PaymentRecordModel> _paymentRecordRepository;
        private readonly IBaseRepository<PatientModel> _patientRepository;
        private readonly IBaseRepository<PatientBalance> _patientBalanceRepository;
        private readonly ILogger<GetRefundInfoHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        public GetRefundInfoHandler(
            IBaseRepository<PaymentRecordModel> paymentRecordRepository,
            IBaseRepository<PatientModel> patientRepository,
            IBaseRepository<PatientBalance> patientBalanceRepository,
            ILogger<GetRefundInfoHandler> logger)
        {
            _paymentRecordRepository = paymentRecordRepository;
            _patientRepository = patientRepository;
            _patientBalanceRepository = patientBalanceRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取退款信息命令
        /// </summary>
        public async Task<ApiResult<RefundInfoDto>> Handle(GetRefundInfoCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation($"开始获取退款信息，PaymentId: {request.PaymentId}, OrderNo: {request.OrderNo}, PatientId: {request.PatientId}");

                // 查询支付记录
                PaymentRecordModel paymentRecord = null;
                
                // 按优先级查询：PaymentId > OrderNo > PatientId
                if (request.PaymentId > 0)
                {
                    paymentRecord = _paymentRecordRepository.GetAll()
                        .Where(p => p.Id == request.PaymentId && !p.IsDeleted && p.IsPaid && p.RefundStatus != "已退款")
                        .FirstOrDefault();
                }
                else if (!string.IsNullOrEmpty(request.OrderNo))
                {
                    paymentRecord = _paymentRecordRepository.GetAll()
                        .Where(p => p.OrderNo == request.OrderNo && !p.IsDeleted && p.IsPaid && p.RefundStatus != "已退款")
                        .FirstOrDefault();
                }
                else if (request.PatientId > 0)
                {
                    // 查询患者最近的一笔已支付且未退款的记录
                    paymentRecord = _paymentRecordRepository.GetAll()
                        .Where(p => p.PatientId == request.PatientId && !p.IsDeleted && p.IsPaid && p.RefundStatus != "已退款")
                        .OrderByDescending(p => p.PayTime)
                        .FirstOrDefault();
                }

                if (paymentRecord == null)
                {
                    _logger.LogWarning($"未找到可退款的支付记录，PaymentId: {request.PaymentId}, OrderNo: {request.OrderNo}, PatientId: {request.PatientId}");
                    return new ApiResult<RefundInfoDto>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "未找到可退款的支付记录"
                    };
                }

                // 查询患者信息
                var patient = _patientRepository.GetAll()
                    .Where(p => p.Id == paymentRecord.PatientId && !p.IsDeleted)
                    .FirstOrDefault();

                if (patient == null)
                {
                    _logger.LogWarning($"未找到ID为 {paymentRecord.PatientId} 的患者");
                    return new ApiResult<RefundInfoDto>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "未找到患者信息"
                    };
                }

                // 查询患者余额
                var balance = _patientBalanceRepository.GetAll()
                    .Where(b => b.PatientId == paymentRecord.PatientId && !b.IsDeleted)
                    .FirstOrDefault();

                decimal cardBalance = balance?.Balance ?? 0;

                // 构建返回结果
                var result = new RefundInfoDto
                {
                    PatientName = patient.Name,
                    IdCard = patient.IdCard,
                    IsSelf = true, // 默认为本人，实际应用中可能需要根据登录用户判断
                    CardBalance = cardBalance,
                    RefundableAmount = paymentRecord.Amount, // 可退款金额默认为支付金额
                    PaymentId = paymentRecord.Id,
                    OrderNo = paymentRecord.OrderNo ?? $"{DateTime.Now:yyyyMMddHHmmss}{paymentRecord.Id}"
                };

                _logger.LogInformation($"成功获取退款信息，PaymentId: {paymentRecord.Id}, OrderNo: {paymentRecord.OrderNo}, PatientName: {patient.Name}");

                return new ApiResult<RefundInfoDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "获取退款信息成功",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取退款信息时发生错误，PaymentId: {request.PaymentId}, OrderNo: {request.OrderNo}, PatientId: {request.PatientId}");
                return new ApiResult<RefundInfoDto>
                {
                    Code = ApiEnum.Error,
                    Msg = $"获取退款信息失败: {ex.Message}"
                };
            }
        }
    }
} 